package com.ruoyi.system.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONObject;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.vo.InspectionPlanTaskDetailsVO;
import com.ruoyi.system.domain.vo.PointProjectVO;
import com.ruoyi.system.domain.vo.PreventionCheckTaskCountVO;
import com.ruoyi.system.entity.InspectionPlanTask;
import com.ruoyi.system.entity.InspectionPlanTaskDetails;
import com.ruoyi.system.entity.InspectionPoint;
import com.ruoyi.system.mapper.InspectionPlanTaskDetailsMapper;
import com.ruoyi.system.service.*;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * 计划任务详情表(InspectionPlanTaskDetails)表服务实现类
 * @since 2022-11-28 17:55:43
 */
@Service("inspectionPlanTaskDetailsService")
public class InspectionPlanTaskDetailsServiceImpl implements InspectionPlanTaskDetailsService {
    @Resource
    private InspectionPlanTaskDetailsMapper inspectionPlanTaskDetailsMapper;
    @Resource
    private InspectionPointService inspectionPointService;
    @Resource
    private InspectionPlanTaskService inspectionPlanTaskService;
    @Resource
    private SysActingService sysActingService;
    @Resource
    private RedisCache redisCache;




    /**
     * 通过ID查询单条数据
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public InspectionPlanTaskDetails queryById(Integer id) {
        return this.inspectionPlanTaskDetailsMapper.queryById(id);
    }

    /**
     * 分页查询
     * @param inspectionPlanTaskDetails 筛选条件
     * @return 查询结果
     */
    @Override
    public List<InspectionPlanTaskDetails> queryByPage(InspectionPlanTaskDetails inspectionPlanTaskDetails) {
        List<InspectionPlanTaskDetails> inspectionPlanTaskDetailsList = inspectionPlanTaskDetailsMapper.queryAllByLimit(inspectionPlanTaskDetails);
        inspectionPlanTaskDetailsList.forEach(i -> {
            Integer pointId = i.getPointId();
            PointProjectVO pointAndProjectById = inspectionPointService.getPointAndProjectById(pointId);
            i.setFormJson(pointAndProjectById.getFormData());
        });
        return inspectionPlanTaskDetailsList;
    }

    /**
     * 新增数据
     * @param inspectionPlanTaskDetails 实例对象
     * @return 实例对象
     */
    @Override
    public InspectionPlanTaskDetails insert(InspectionPlanTaskDetails inspectionPlanTaskDetails) {
        this.inspectionPlanTaskDetailsMapper.insert(inspectionPlanTaskDetails);
        return inspectionPlanTaskDetails;
    }

    /**
     * 修改数据
     * @param inspectionPlanTaskDetails 实例对象
     * @return 实例对象
     */
    @Override
    public InspectionPlanTaskDetails update(InspectionPlanTaskDetails inspectionPlanTaskDetails) {
        this.inspectionPlanTaskDetailsMapper.update(inspectionPlanTaskDetails);
        return this.queryById(inspectionPlanTaskDetails.getId());
    }

    /**
     * 通过主键删除数据
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.inspectionPlanTaskDetailsMapper.deleteById(id) > 0;
    }

    @Override
    public void insertBatch(List<InspectionPlanTaskDetails> inspectionPlanTaskDetailsList) {
        this.inspectionPlanTaskDetailsMapper.insertBatch(inspectionPlanTaskDetailsList);
    }


    // src和source比较上下不可以超过num
    public Boolean checkUser(Double src,Double source,Double num) {
        BigDecimal add = NumberUtil.add(source, BigDecimal.valueOf(num));
        BigDecimal sub = NumberUtil.sub(source, BigDecimal.valueOf(num));
        int addCompare = NumberUtil.compare(src, add.doubleValue());
        int subCompare = NumberUtil.compare(src, sub.doubleValue());
        if (addCompare < 0 && subCompare > 0) {
            return false;
        }
        return true;
    }

    /**
     * 完成任务
     * @param inspectionPlanTaskDetails
     */
    @Override
    public void completeTask(InspectionPlanTaskDetails inspectionPlanTaskDetails) {
        // 校验巡检人员是否是执行任务人员
        int userId = SecurityUtils.getUserId().intValue();
        Integer planTaskId = inspectionPlanTaskDetails.getPlanTaskId();
        Integer pointId = inspectionPlanTaskDetails.getPointId();
        InspectionPoint inspectionPoint = inspectionPointService.queryById(pointId);

        if (0 == inspectionPoint.getIsEnable()) {
            // 获取当前用户名称
            String nickName = SecurityUtils.getLoginUser().getUser().getNickName();
            List<Object> cacheList = redisCache.getCacheListNew(nickName);
            if(!CollectionUtils.isEmpty(cacheList)){
                Object obt = cacheList.get(0);
                JSONObject jsonObject = new JSONObject(obt);
                // 经度
                Double longitude = jsonObject.getDouble("longitude");
                // 纬度
                Double latitude = jsonObject.getDouble("latitude");
                // 点位经度
                Double pointLongitude = Double.valueOf(inspectionPoint.getLongitude());
                // 点位纬度
                Double pointLatitude = Double.valueOf(inspectionPoint.getLatitude());
                // 比较经度
                Boolean aBoolean1 = checkUser(latitude, pointLatitude, 0.000009);
                // 比较纬度
                Boolean aBoolean = checkUser(longitude, pointLongitude, 0.000009);
                if (aBoolean1 || aBoolean ) {
                    throw new ServiceException("当前位置无法完成任务，请前往据点位10米范围内",500);
                }
            }
        }

        InspectionPlanTask byId = inspectionPlanTaskService.queryById(planTaskId);
        if (!byId.getPlanTaskState().equals("未完成")) {
            throw new ServiceException("改巡检任务已无法继续巡检",500);
        }
        String planUserIds = byId.getPlanUserIds();
        String[] split = planUserIds.split(",");
        Boolean at = true;
        for (int i = 0; i < split.length; i++) {
            if (userId == Integer.valueOf(split[i])) {
                at = false;
                break;
            }
        }
        if (at) {
            throw new ServiceException("无权操作",500);
        }
        // 加巡检点排序
        Integer pointOrder = inspectionPoint.getPointOrder();
        Boolean al1 = false;
        if (pointOrder != 0 && pointOrder > 1) {
            // 获取排序上一次的点位ID
            InspectionPoint poIntOrderId =  inspectionPointService.getUpPoIntOrderId(inspectionPoint.getRouteId(), pointOrder-1);
            // 根据点位ID与planTaskId查看是否排查完成
            if (ObjectUtils.isNotEmpty(poIntOrderId)){
                InspectionPlanTaskDetails taskDetails = inspectionPlanTaskDetailsMapper.queryTaskCompletion(poIntOrderId.getId(),planTaskId);
                if (!taskDetails.getCheckState().equals("已排查")){
                    al1 = true;
                }
            } else {
                throw new ServiceException("请按照顺序配置巡检任务",500);
            }
        }
        if (al1) {
            throw new ServiceException("请按照顺序完成巡检任务",500);
        }

        inspectionPlanTaskDetails.setCheckUser(SecurityUtils.getUsername());
        inspectionPlanTaskDetails.setCheckTime(DateUtil.now());
        inspectionPlanTaskDetails.setCheckState("已排查");
        this.inspectionPlanTaskDetailsMapper.update(inspectionPlanTaskDetails);
        // 统计还剩多少未排查任务
        Integer count = inspectionPlanTaskDetailsMapper.countCheckStateByTaskId(planTaskId);
        // 未剩余排查任务---完成计划任务---完成待办
        if (count == 0) {
            InspectionPlanTask inspectionPlanTask = new InspectionPlanTask();
            inspectionPlanTask.setId(planTaskId);
            inspectionPlanTask.setPlanTaskState("已完成");
            inspectionPlanTaskService.update(inspectionPlanTask);
            sysActingService.completeActing("巡检","巡检任务",planTaskId);
        }
    }

    @Override
    public void updateStateByPointId(Integer id) {
        inspectionPlanTaskDetailsMapper.updateStateByPointId(id);
    }

    @Override
    public int getARxj(String day) {
        return inspectionPlanTaskDetailsMapper.getARxj(day);
    }

    @Override
    public int getAYxj(String month) {
        return inspectionPlanTaskDetailsMapper.getAYxj(month);
    }

    @Override
    public int getAllxj() {
        return inspectionPlanTaskDetailsMapper.getAllxj();
    }


    @Override
    public  List<PreventionCheckTaskCountVO> getTaskDay(String dayTo) {
        return inspectionPlanTaskDetailsMapper.getTaskDay(dayTo);
    }

    @Override
    public  List<PreventionCheckTaskCountVO> getTaskMonth(String monthTo) {
        return inspectionPlanTaskDetailsMapper.getTaskMonth(monthTo);
    }

    @Override
    public List<PreventionCheckTaskCountVO> getAllTask() {
        return inspectionPlanTaskDetailsMapper.getAllTask();
    }

    @Override
    public List<InspectionPlanTaskDetailsVO> queryAllVO(InspectionPlanTaskDetailsVO inspectionPlanTaskDetailsVO) {
        return inspectionPlanTaskDetailsMapper.queryAllVO(inspectionPlanTaskDetailsVO);
    }

}
